package cm.tl.pms.util;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ObjectListMerger<T> {

    public static <T> List<T> merge(List<T> objectList, Class<T> clazz, String uniqueField, String separator) {
        try {
            // 通过反射获取唯一字段
            Field uniqueFieldObj = clazz.getDeclaredField(uniqueField);
            uniqueFieldObj.setAccessible(true);

            // 按照唯一字段进行分组
            Map<Object, List<T>> groupedObjects = objectList.stream()
                    .collect(Collectors.groupingBy(obj -> {
                        try {
                            return uniqueFieldObj.get(obj);
                        } catch (IllegalAccessException e) {
                            throw new RuntimeException(e);
                        }
                    }));

            List<T> mergedList = new ArrayList<>();
            for (Map.Entry<Object, List<T>> entry : groupedObjects.entrySet()) {
                T mergedObject = clazz.getDeclaredConstructor().newInstance();
                List<T> group = entry.getValue();

                // 使用Map来记录已经合并过的字段值
                Map<String, String> mergedFields = new HashMap<>();

                // 遍历每个分组中的对象，合并字段
                for (T obj : group) {
                    Field[] fields = clazz.getDeclaredFields();
                    for (Field field : fields) {
                        if (!field.getName().equals("serialVersionUID")) { // 跳过serialVersionUID字段
                            field.setAccessible(true);
                            Object value = field.get(obj);
                            if (value != null) {
                                String fieldName = field.getName();
                                if (!mergedFields.containsKey(fieldName)) {
                                    field.set(mergedObject, value);
                                    mergedFields.put(fieldName, (value instanceof String) ? (String) value : value.toString());
                                } else if (mergedFields.get(fieldName) instanceof String && !fieldName.equals(uniqueField)) {
                                    String existingValue = mergedFields.get(fieldName);
                                    if (!existingValue.contains(value.toString())) {
                                        field.set(mergedObject, existingValue + separator + value);
                                        mergedFields.put(fieldName, existingValue + separator + value);
                                    }
                                }
                            }
                        }
                    }
                }
                mergedList.add(mergedObject);
            }
            return mergedList;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
